package com.ljf.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljf.admin.POJO.*;
import com.ljf.admin.mapper.*;
import com.ljf.admin.service.SysRoleService;
import com.ljf.framework.util.tree.TreeObject;
import com.ljf.framework.util.tree.TreeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @Auther: lijinfeng
 * @Date: 2022/4/21
 * @Description 描述:
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Autowired
    private SysRoleMapper roleMapper;

    @Autowired
    private SysUserRoleMapper userRoleMapper;

    @Autowired
    private SysDeptMapper deptMapper;

    @Autowired
    private SysMenuMapper menuMapper;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Autowired
    private SysRoleDeptMapper sysRoleDeptMapper;


    @Override
    public int updateBatch(List<SysRole> list) {
        return baseMapper.updateBatch(list);
    }

    @Override
    public int updateBatchSelective(List<SysRole> list) {
        return baseMapper.updateBatchSelective(list);
    }

    @Override
    public int batchInsert(List<SysRole> list) {
        return baseMapper.batchInsert(list);
    }

    @Override
    @Cacheable(value = "role=100", key = "#root.targetClass+'userId'+#userId")
    public List<SysRole> selectRolesByUserId(Long userId) {

        List<SysRole> roles = roleMapper.selectRolesByUserId(userId);
        // 填充menuIds, deptIds
        roles.forEach(role -> {
            List<SysDept> deptList = deptMapper.selectDeptListByRoleId(role.getId());
            role.setDeptList(Collections.singletonList(deptList));
            List<SysMenu> menuList = menuMapper.selectMenuListByRoleId(role.getId());
            role.setMenuList(Collections.singletonList(menuList));
        });

        return roles;
    }

    @Override
    public List<SysRole> getRolesByUserId(Long userId) {
        List<SysRole> roleList = roleMapper.selectRolesByUserId(userId);
        return roleList;
    }

    @Transactional
    @Override
    public void setRoleId(Long userId, Long roleId) {
        QueryWrapper<SysUserRole> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("user_id", userId);
        userRoleMapper.delete(objectQueryWrapper);
        userRoleMapper.insert(new SysUserRole(userId, roleId));
    }

    @Override
    public List<SysRole> getList() {
        QueryWrapper<SysRole> qw = new QueryWrapper<>();
        List<SysRole> roleList = roleMapper.selectList(qw);

        roleList.forEach(role -> {
            List<SysMenu> menus = menuMapper.selectMenuListByRoleId(role.getId());
            List<TreeObject> tree = TreeUtil.getTree(menus);
            role.setMenuList(tree);
        });
        return roleList;
    }

    @Override
    public List<SysMenu> deleteRoleMenu(Long roleId, Long... menus) {
        // 如果menus是父菜单，需要把他以及他的子级全部删除
        List<Long> list = menuMapper.getChildrenMenuIdList(menus);
        list.addAll(Arrays.asList(menus));
        sysRoleMenuMapper.deleteRoleMenu(roleId, list);
        return menuMapper.getListByRoleId(roleId);
    }

    /*
    需要写明事务管理器名称 不然默认使用transactionManager,将导致事务不可用
     */
    @Transactional(value = "systemTransactionManager")
    @Override
    public void addRole(SysRole sysRole) {

        List<Object> menuList = sysRole.getMenuList();
        roleMapper.insert(sysRole);

        List<SysRoleMenu> list = new ArrayList<>();
        menuList.forEach(item -> {
            list.add(new SysRoleMenu(sysRole.getId(), (long) (int) item));
        });
        sysRoleMenuMapper.batchInsert(list);
    }

    @Override
    @Transactional(value = "systemTransactionManager")
    public void editRole(SysRole sysRole) {
        List<Object> menuList = sysRole.getMenuList();
        roleMapper.updateById(sysRole);
        QueryWrapper<SysRoleMenu> qw = new QueryWrapper<>();
        qw.eq("role_id", sysRole.getId());
        sysRoleMenuMapper.delete(qw);
        List<SysRoleMenu> list = new ArrayList<>();
        menuList.forEach(item -> {
            list.add(new SysRoleMenu(sysRole.getId(), (long) (int) item));
        });
        if (list.size() > 0)
            sysRoleMenuMapper.batchInsert(list);
    }

    @Transactional(value = "systemTransactionManager")
    @Override
    public void deleteRole(Long roleId) {
        roleMapper.deleteById(roleId);
        QueryWrapper<SysRoleMenu> qw = new QueryWrapper<>();
        qw.eq("role_id", roleId);
        sysRoleMenuMapper.delete(qw);
        QueryWrapper<SysRoleDept> qw2 = new QueryWrapper<>();
        qw2.eq("role_id", roleId);
        sysRoleDeptMapper.delete(qw2);
    }
}
